package br.com.tcc.systemdx.commons.persistence;

import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.Criterion;
/**
 * FROM: http://www.hibernate.org/328.html
 * 
 * This is a pattern for Data Access Objects with JDK 5.0, from the CaveatEmptor 
 * example application. It is also explained in the book Java Persistence with 
 * Hibernate. Two links you might find useful: Sessions and transactions and 
 * Open Session in View.
 *
 * This time I based the DAO example on interfaces. Tools like Hibernate 
 * already provide database portability, so persistence layer portability 
 * shouldn't be a driving motivation for interfaces. However, DAO interfaces 
 * make sense in more complex applications, when several persistence services 
 * are encapsulate in one persistence layer. I'd say that you should use 
 * Hibernate (or Java Persistence APIs) directly in most cases, the best reason 
 * to use an additional DAO layer is higher abstraction (e.g. methods like 
 * getMaximumBid() instead of session.createQuery(...) repeated a dozen times).
 * 
 * @author Felipe Rico
 *
 * @param <T>
 * @param <ID>
 */
public interface GenericDAO<T, ID extends Serializable> {

    T findById(ID id, boolean lock);
    
    T findById(ID id);

    List<T> findAll();

    List<T> findByExample(T exampleInstance, String[] excludeProperty);
    
    T makePersistent(T entity);
    
    T updateCopy(T entity);
    
    void flush();

    void makeTransient(T entity);
    

    /**
     * Usado para a paginação
     * @param maxResults
     * @param firstResult
     * @param sortPropertyName
     * @param ascending
     * @param criterion
     * @return
     */
	List<T> findByCriteria(int maxResults, int firstResult,
			String sortPropertyName, boolean ascending, Criterion... criterion);
	
    
	/**
	 * Usado para a paginação
	 * @param criterion
	 * @return
	 */
	int countByCriteria(Criterion... criterion);
	
	/**
	 * Recarrega a entidade do banco de dados
	 * @param entity
	 * @return
	 */
	T refresh(T entity);
}
